home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / gpt32src.zip / PARSE.C < prev    next >
C/C++ Source or Header  |  1992-03-25  |  11KB  |  571 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: parse.c,v 3.26 92/03/24 22:34:33 woo Exp Locker: woo $";
  3. #endif
  4.  
  5. /* GNUPLOT - parse.c */
  6. /*
  7.  * Copyright (C) 1986, 1987, 1990, 1991, 1992   Thomas Williams, Colin Kelley
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted, 
  11.  * provided that the above copyright notice appear in all copies and 
  12.  * that both that copyright notice and this permission notice appear 
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the modified code.  Modifications are to be distributed 
  17.  * as patches to released version.
  18.  *  
  19.  * This software is provided "as is" without express or implied warranty.
  20.  * 
  21.  *
  22.  * AUTHORS
  23.  * 
  24.  *   Original Software:
  25.  *     Thomas Williams,  Colin Kelley.
  26.  * 
  27.  *   Gnuplot 2.0 additions:
  28.  *       Russell Lang, Dave Kotz, John Campbell.
  29.  *
  30.  *   Gnuplot 3.0 additions:
  31.  *       Gershon Elber and many others.
  32.  * 
  33.  * Send your comments or suggestions to 
  34.  *  info-gnuplot@ames.arc.nasa.gov.
  35.  * This is a mailing list; to join it send a note to 
  36.  *  info-gnuplot-request@ames.arc.nasa.gov.  
  37.  * Send bug reports to
  38.  *  bug-gnuplot@ames.arc.nasa.gov.
  39.  */
  40.  
  41. #include <stdio.h>
  42. #include <setjmp.h>
  43. #include <signal.h>
  44. #include <errno.h>
  45. #include <math.h>
  46. #include "plot.h"
  47.  
  48. #ifndef vms
  49. #ifndef __ZTC__
  50. extern int errno;
  51. #endif
  52. #endif
  53.  
  54. extern int num_tokens,c_token;
  55. extern struct lexical_unit token[];
  56. extern char c_dummy_var[MAX_NUM_VAR][MAX_ID_LEN+1];    /* name of current dummy vars */
  57. extern struct udft_entry *dummy_func;    /* pointer to dummy variable's func */
  58.  
  59. struct value *pop(),*integer(),*complex();
  60. struct at_type *temp_at(), *perm_at();
  61. struct udft_entry *add_udf();
  62. struct udvt_entry *add_udv();
  63. union argument *add_action();
  64.  
  65. struct at_type at;
  66. static jmp_buf fpe_env;
  67.  
  68. #define dummy (struct value *) 0
  69.  
  70. #ifdef __TURBOC__
  71. void fpe()
  72. #else
  73. #if defined( __ZTC__ ) || defined( _CRAY ) || defined( sgi )
  74. void fpe(an_int)
  75. int an_int;
  76. #else
  77. #ifdef NEXT
  78. void fpe(int an_int)
  79. #else
  80. #ifdef sgi
  81. void fpe(int sig, int code, struct sigcontext *sc)
  82. /*void fpe(an_int)
  83. int an_int;*/
  84. #else
  85. fpe()
  86. #endif
  87. #endif
  88. #endif /* __ZTC__ || _CRAY */
  89. #endif
  90. {
  91. #ifdef PC    /* thanks to lotto@wjh12.UUCP for telling us about this  */
  92.     _fpreset();
  93. #endif
  94.     (void) signal(SIGFPE, fpe);
  95.     undefined = TRUE;
  96.     longjmp(fpe_env, TRUE);
  97. }
  98.  
  99.  
  100. #ifdef apollo
  101. #include <apollo/base.h>
  102. #include <apollo/pfm.h>
  103. #include <apollo/fault.h>
  104.  
  105. /*
  106.   On an Apollo, the OS can signal a couple errors that are not mapped
  107.   into SIGFPE, namely signalling NaN and branch on an unordered
  108.   comparison.  I suppose there are others, but none of these are documented,
  109.   so I handle them as they arise.
  110.  
  111.   Anyway, we need to catch these faults and signal SIGFPE.
  112. */
  113.  
  114. pfm_$fh_func_val_t apollo_sigfpe(pfm_$fault_rec_t& fault_rec)
  115. {
  116.     kill(getpid(), SIGFPE);
  117.     return pfm_$continue_fault_handling;
  118. }
  119.  
  120. apollo_pfm_catch()
  121. {
  122.     status_$t status;
  123.     pfm_$establish_fault_handler(fault_$fp_bsun, pfm_$fh_backstop,
  124.                  apollo_sigfpe, &status);
  125.     pfm_$establish_fault_handler(fault_$fp_sig_nan, pfm_$fh_backstop,
  126.                  apollo_sigfpe, &status);
  127. }
  128. #endif
  129.  
  130.  
  131. evaluate_at(at_ptr,val_ptr)
  132. struct at_type *at_ptr;
  133. struct value *val_ptr;
  134. {
  135.     double temp, real();
  136.  
  137.     undefined = FALSE;
  138.     errno = 0;
  139.     reset_stack();
  140.     if (setjmp(fpe_env))
  141.         return;                /* just bail out */
  142.     (void) signal(SIGFPE, fpe);    /* catch core dumps on FPEs */
  143.  
  144.     execute_at(at_ptr);
  145.  
  146.     (void) signal(SIGFPE, SIG_DFL);
  147.  
  148.     if (errno == EDOM || errno == ERANGE) {
  149.         undefined = TRUE;
  150.     } else {
  151.         (void) pop(val_ptr);
  152.         check_stack();
  153.     }
  154. /* At least one machine (ATT 3b1) computes Inf without a SIGFPE */
  155.     temp = real(val_ptr);
  156.     if (temp > VERYLARGE || temp < -VERYLARGE) {
  157.         undefined = TRUE;
  158.     }
  159. }
  160.  
  161.  
  162. struct value *
  163. const_express(valptr)
  164. struct value *valptr;
  165. {
  166. register int tkn = c_token;
  167.     if (END_OF_COMMAND)
  168.         int_error("constant expression required",c_token);
  169.     evaluate_at(temp_at(),valptr);    /* run it and send answer back */
  170.     if (undefined) {
  171.         int_error("undefined value",tkn);
  172.     }
  173.     return(valptr);
  174. }
  175.  
  176.  
  177. struct at_type *
  178. temp_at()    /* build a static action table and return its pointer */
  179. {
  180.     at.a_count = 0;        /* reset action table !!! */
  181.     express();
  182.     return(&at);
  183. }
  184.  
  185.  
  186. /* build an action table, put it in dynamic memory, and return its pointer */
  187.  
  188. struct at_type *
  189. perm_at()
  190. {
  191. register struct at_type *at_ptr;
  192. register unsigned int len;
  193.  
  194.     (void) temp_at();
  195.     len = sizeof(struct at_type) -
  196.         (MAX_AT_LEN - at.a_count)*sizeof(struct at_entry);
  197.     at_ptr = (struct at_type *) alloc(len, "action table");
  198.      (void) memcpy(at_ptr,&at,len);
  199.     return(at_ptr);
  200. }
  201.  
  202.  
  203. #ifdef NOCOPY
  204. /*
  205.  * cheap and slow version of memcpy() in case you don't have one
  206.  */
  207. memcpy(dest,src,len)
  208. char *dest,*src;
  209. unsigned int len;
  210. {
  211.     while (len--)
  212.         *dest++ = *src++;
  213. }
  214. #endif /* NOCOPY */
  215.  
  216.  
  217. express()  /* full expressions */
  218. {
  219.     xterm();
  220.     xterms();
  221. }
  222.  
  223. xterm()  /* ? : expressions */
  224. {
  225.     aterm();
  226.     aterms();
  227. }
  228.  
  229.  
  230. aterm()
  231. {
  232.     bterm();
  233.     bterms();
  234. }
  235.  
  236.  
  237. bterm()
  238. {
  239.     cterm();
  240.     cterms();
  241. }
  242.  
  243.  
  244. cterm()
  245. {
  246.     dterm();
  247.     dterms();
  248. }
  249.  
  250.  
  251. dterm()
  252. {    
  253.     eterm();
  254.     eterms();
  255. }
  256.  
  257.  
  258. eterm()
  259. {
  260.     fterm();
  261.     fterms();
  262. }
  263.  
  264.  
  265. fterm()
  266. {
  267.     gterm();
  268.     gterms();
  269. }
  270.  
  271.  
  272. gterm()
  273. {
  274.     hterm();
  275.     hterms();
  276. }
  277.  
  278.  
  279. hterm()
  280. {
  281.     unary(); /* - things */
  282.     iterms(); /* * / % */
  283. }
  284.  
  285.  
  286. factor()
  287. {
  288. register int value;
  289.  
  290.     if (equals(c_token,"(")) {
  291.         c_token++;
  292.         express();
  293.         if (!equals(c_token,")"))
  294.             int_error("')' expected",c_token);
  295.         c_token++;
  296.     }
  297.     else if (isnumber(c_token)) {
  298.         convert(&(add_action(PUSHC)->v_arg),c_token);
  299.         c_token++;
  300.     }
  301.     else if (isletter(c_token)) {
  302.         if ((c_token+1 < num_tokens)  && equals(c_token+1,"(")) {
  303.             value = standard(c_token);
  304.             if (value) {    /* it's a standard function */
  305.                 c_token += 2;
  306.                 express();
  307.                 if (!equals(c_token,")"))
  308.                     int_error("')' expected",c_token);
  309.                 c_token++;
  310.                 (void) add_action(value);
  311.             }
  312.             else {
  313.                 int call_type = (int )CALL;
  314.                 value = c_token;
  315.                 c_token += 2;
  316.                 express();
  317.                 if (equals(c_token, ",")) {
  318.                     c_token += 1;
  319.                     express();
  320.                     call_type = (int )CALL2;
  321.                 }
  322.                 if (!equals(c_token,")"))
  323.                     int_error("')' expected",c_token);
  324.                 c_token++;
  325.                 add_action(call_type)->udf_arg = add_udf(value);
  326.             }
  327.         }
  328.         else {
  329.             if (equals(c_token,c_dummy_var[0])) {
  330.                 c_token++;
  331.                 add_action(PUSHD1)->udf_arg = dummy_func;
  332.             }
  333.             else if (equals(c_token,c_dummy_var[1])) {
  334.                 c_token++;
  335.                 add_action(PUSHD2)->udf_arg = dummy_func;
  336.             }
  337.             else {
  338.                 add_action(PUSH)->udv_arg = add_udv(c_token);
  339.                 c_token++;
  340.             }
  341.         }
  342.     } /* end if letter */
  343.     else
  344.         int_error("invalid expression ",c_token);
  345.  
  346.     /* add action code for ! (factorial) operator */
  347.     while (equals(c_token,"!")) {
  348.         c_token++;
  349.         (void) add_action(FACTORIAL);
  350.     }
  351.     /* add action code for ** operator */
  352.     if (equals(c_token,"**")) {
  353.             c_token++;
  354.             unary();
  355.             (void) add_action(POWER);
  356.     }
  357.  
  358. }
  359.  
  360.  
  361.  
  362. xterms()
  363. {  /* create action code for ? : expressions */
  364.  
  365.     if (equals(c_token,"?")) {
  366.         register int savepc1, savepc2;
  367.         register union argument *argptr1,*argptr2;
  368.         c_token++;
  369.         savepc1 = at.a_count;
  370.         argptr1 = add_action(JTERN);
  371.         express();
  372.         if (!equals(c_token,":"))
  373.             int_error("expecting ':'",c_token);
  374.         c_token++;
  375.         savepc2 = at.a_count;
  376.         argptr2 = add_action(JUMP);
  377.         argptr1->j_arg = at.a_count - savepc1;
  378.         express();
  379.         argptr2->j_arg = at.a_count - savepc2;
  380.     }
  381. }
  382.  
  383.  
  384. aterms()
  385. {  /* create action codes for || operator */
  386.  
  387.     while (equals(c_token,"||")) {
  388.         register int savepc;
  389.         register union argument *argptr;
  390.         c_token++;
  391.         savepc = at.a_count;
  392.         argptr = add_action(JUMPNZ);    /* short-circuit if already TRUE */
  393.         aterm();
  394.         argptr->j_arg = at.a_count - savepc;/* offset for jump */
  395. #if defined(AMIGA_LC_5_1) || defined(AMIGA_AC_5)
  396.         (void) add_action(ABOOL);
  397. #else
  398.         (void) add_action(BOOLE);
  399. #endif
  400.     }
  401. }
  402.  
  403.  
  404. bterms()
  405. { /* create action code for && operator */
  406.  
  407.     while (equals(c_token,"&&")) {
  408.         register int savepc;
  409.         register union argument *argptr;
  410.         c_token++;
  411.         savepc = at.a_count;
  412.         argptr = add_action(JUMPZ);    /* short-circuit if already FALSE */
  413.         bterm();
  414.         argptr->j_arg = at.a_count - savepc;/* offset for jump */
  415. #if defined(AMIGA_LC_5_1) || defined(AMIGA_AC_5)
  416.         (void) add_action(ABOOL);
  417. #else
  418.         (void) add_action(BOOLE);
  419. #endif
  420.     }
  421. }
  422.  
  423.  
  424. cterms()
  425. { /* create action code for | operator */
  426.  
  427.     while (equals(c_token,"|")) {
  428.         c_token++;
  429.         cterm();
  430.         (void) add_action(BOR);
  431.     }
  432. }
  433.  
  434.  
  435. dterms()
  436. { /* create action code for ^ operator */
  437.  
  438.     while (equals(c_token,"^")) {
  439.         c_token++;
  440.         dterm();
  441.         (void) add_action(XOR);
  442.     }
  443. }
  444.  
  445.  
  446. eterms()
  447. { /* create action code for & operator */
  448.  
  449.     while (equals(c_token,"&")) {
  450.         c_token++;
  451.         eterm();
  452.         (void) add_action(BAND);
  453.     }
  454. }
  455.  
  456.  
  457. fterms()
  458. { /* create action codes for == and != operators */
  459.  
  460.     while (TRUE) {
  461.         if (equals(c_token,"==")) {
  462.             c_token++;
  463.             fterm();
  464.             (void) add_action(EQ);
  465.         }
  466.         else if (equals(c_token,"!=")) {
  467.             c_token++;
  468.             fterm();
  469.             (void) add_action(NE);
  470.         }
  471.         else break;
  472.     }
  473. }
  474.  
  475.  
  476. gterms()
  477. { /* create action code for < > >= or <= operators */
  478.     
  479.     while (TRUE) {
  480.         /* I hate "else if" statements */
  481.         if (equals(c_token,">")) {
  482.             c_token++;
  483.             gterm();
  484.             (void) add_action(GT);
  485.         }
  486.         else if (equals(c_token,"<")) {
  487.             c_token++;
  488.             gterm();
  489.             (void) add_action(LT);
  490.         }        
  491.         else if (equals(c_token,">=")) {
  492.             c_token++;
  493.             gterm();
  494.             (void) add_action(GE);
  495.         }
  496.         else if (equals(c_token,"<=")) {
  497.             c_token++;
  498.             gterm();
  499.             (void) add_action(LE);
  500.         }
  501.         else break;
  502.     }
  503.  
  504. }
  505.  
  506.  
  507.  
  508. hterms()
  509. { /* create action codes for + and - operators */
  510.  
  511.     while (TRUE) {
  512.             if (equals(c_token,"+")) {
  513.                 c_token++;
  514.                 hterm();
  515.                 (void) add_action(PLUS);
  516.             }
  517.             else if (equals(c_token,"-")) {
  518.                 c_token++;
  519.                 hterm();
  520.                 (void) add_action(MINUS);
  521.             }
  522.             else break;
  523.     }
  524. }
  525.  
  526.  
  527. iterms()
  528. { /* add action code for * / and % operators */
  529.  
  530.     while (TRUE) {
  531.             if (equals(c_token,"*")) {
  532.                 c_token++;
  533.                 unary();
  534.                 (void) add_action(MULT);
  535.             }
  536.             else if (equals(c_token,"/")) {
  537.                 c_token++;
  538.                 unary();
  539.                 (void) add_action(DIV);
  540.             }
  541.             else if (equals(c_token,"%")) {
  542.                 c_token++;
  543.                 unary();
  544.                 (void) add_action(MOD);
  545.             }
  546.             else break;
  547.     }
  548. }
  549.  
  550.  
  551. unary()
  552. { /* add code for unary operators */
  553.     if (equals(c_token,"!")) {
  554.         c_token++;
  555.         unary();
  556.         (void) add_action(LNOT);
  557.     }
  558.     else if (equals(c_token,"~")) {
  559.         c_token++;
  560.         unary();
  561.         (void) add_action(BNOT);
  562.     }
  563.     else if (equals(c_token,"-")) {
  564.         c_token++;
  565.         unary();
  566.         (void) add_action(UMINUS);
  567.     }
  568.     else
  569.         factor();
  570. }
  571.